package com.atguigu.shardingjdbcdemo.algorithm;

import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;


/**
 * 自定义实现 范围分片算法（RangeShardingAlgorithm）接口
 * 数据库DB的范围分片
 *
 * @author zzjx
 * @version 1.0
 * fileName PreciseShardingDBAlgorithm1
 * createTime 2021/10/20  19:21
 */
public class RangeShardingDBAlgorithm implements RangeShardingAlgorithm<Integer> {


    @Override
    public Collection<String> doSharding(final Collection<String> databaseNames,
                                         final RangeShardingValue<Integer> shardingValue) {

        /**
         * 自定义SQL -> SELECT *  FROM t_order WHERE order _id Between 2000 and 4000
         * ds0.t_order: 1000 ~ 3000
         * ds1.t_order: 3001 ~ 5000
         * ds2.t_order: 5001 ~ 7000
         *
         * 执行路由后的SQL 应为：
         * SELECT *  FROM ds0.t_order WHERE order _id Between 2000 and 3000
         * SELECT *  FROM ds1.t_order WHERE order _id Between 3001 and 4000
         *
         * 此处约定 user_id 与 总数据源取余数
         *
         */
        Set<String> result = new LinkedHashSet<>();
        Collection<String> collect = new ArrayList<>();
        // 从sql 中获取 Between 2000 and 4000   的值，将2000 赋值给 lower,  4000 赋值给 upper
//        int lower = shardingValue.getValueRange().lowerEndpoint();
//        int upper = shardingValue.getValueRange().upperEndpoint();
//        for (int i = lower; i <= upper; i++) {
//            for (String each : databaseNames) { //ds0,ds1
//                if (each.endsWith(i % databaseNames.size() + "")) {
//                    result.add(each);
//                }
//            }
//        }
        //SQL:  select * from course where user_id between 200 and300
        for (String each : databaseNames) {

            //  此方法如果参数所表示的字符序列是由该对象表示的字符序列的后缀返回true, 否则为false;
            //  请注意，如果参数是空字符串或等于此String对象由equals（Object）方法确定结果为 true。
            //  String Str = new String("This is really not immutable!!");   retVal = Str.endsWith( "immutable!!" )
            //  为true
            //  ds0.startsWith("d") -> true ; d代表course类型数据库  u代表用户类型数据库

            for (String database : databaseNames) {
                if (database.startsWith("d")) {
                    collect.add(database);
                }
            }
            //进行取余算法，偶数分到edu_db_1 奇数分到edu_db_2中去
            for (String c : collect) {
               result.add(c);
            }

        }
        return result;
    }
}

